﻿using System;
using System.Collections.Generic;

namespace RedNoteModule
{
    /// <summary>
    /// 红点管理器
    /// </summary>
    public partial class RedNoteMgr
    {
        private static RedNoteMgr m_instance;
        public static RedNoteMgr Instance
        {
            get
            {
                if (m_instance == null)
                {
                    m_instance = new RedNoteMgr();
                }
                return m_instance;
            }
        }
        
        private RedNoteRelationTree m_relationTree;
        
        private Dictionary<string, List<IRedNoteVisualComponent>> m_visualComponents = new Dictionary<string, List<IRedNoteVisualComponent>>();

        private RedNoteMgr()
        {
            m_relationTree = new RedNoteRelationTree();
            BuildRedNoteTree();
        }

        #region 红点关系树维护

        public void AddRelation(RedNoteType parent, params RedNoteType[] children)
        {
            string[] childrenString = new string[children.Length];
            for (int i = 0; i < children.Length; i++)
            {
                childrenString[i] = children[i].ToString();
            }
            AddRelation(parent.ToString(), childrenString);
        }

        public void AddRelation(string parent, params string[] children)
        {
            m_relationTree.AddRelations(parent, children);
        }

        public void RemoveRelation(RedNoteType parent, RedNoteType children)
        {
            RemoveRelation(parent.ToString(), children.ToString());
        }

        public void RemoveRelation(string parent, string child)
        {
            m_relationTree.RemoveRelation(parent, child);
        }

        #endregion

        #region 红点逻辑状态发出

        public void SetRedNoteValue(RedNoteType key, bool value)
        {
            SetRedNoteValue(key.ToString(), value);
        }
        
        /// <summary>
        /// 设置红点状态
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="allowNotLeaf"></param>
        public void SetRedNoteValue(string key, bool value)
        {
            if (!m_relationTree.ContainsNote(key))
            {
                return;
            }
            m_relationTree.SetState(key, value);   
        }

        public bool GetRedNoteValue(RedNoteType key)
        {
            return GetRedNoteValue(key.ToString());
        }
        
        /// <summary>
        /// 获取红点状态
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool GetRedNoteValue(string key)
        {
            return m_relationTree.GetNoteState(key);
        }

        #endregion

        #region 提供给视觉组件的接口

        public bool AddRedNoteChangeListener(string key, IRedNoteVisualComponent visualComponent)
        {
            if (!m_visualComponents.TryGetValue(key, out List<IRedNoteVisualComponent> container))
            {
                container = new List<IRedNoteVisualComponent>();
                m_visualComponents.Add(key, container);
            }

            if (container.IndexOf(visualComponent) >= 0)
            {
                return false;
            }

            container.Add(visualComponent);
            bool state = GetRedNoteValue(key);
            visualComponent.RedNoteValueChange(state);
            
            return true;
        }

        public void RemoveRedNoteChangeListener(string key, IRedNoteVisualComponent visualComponent)
        {
            if (m_visualComponents.TryGetValue(key, out List<IRedNoteVisualComponent> container))
            {
                int index = container.IndexOf(visualComponent);
                if (index >= 0)
                {
                    container.RemoveAt(index);
                }
            }
        }
        
        #endregion

        #region 每帧Update

        public void Update()
        {
            if (m_relationTree != null)
            {
                var dirtyRedNotes = m_relationTree.GetAllDirtyMarkRedNote();
                foreach (var redNote in dirtyRedNotes)
                {
                    RefreshVisualComponent(redNote.Key, redNote.Value);
                }
                m_relationTree.ClearAllDirtyRedNoteMark();
            }
        }

        /// <summary>
        /// 刷新视觉组件显示
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        private void RefreshVisualComponent(string key, bool value)
        {
            if (m_visualComponents.TryGetValue(key, out List<IRedNoteVisualComponent> container))
            {
                for (int i = 0; i < container.Count; i++)
                {
                    container[i].RedNoteValueChange(value);
                }
            }
        }

        #endregion
    }
}